package com.umsoft.smart.framework.helper;

import com.umsoft.smart.framework.annotation.Controller;
import com.umsoft.smart.framework.annotation.Service;
import com.umsoft.smart.framework.util.ClassUtil;

import java.lang.annotation.Annotation;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 类操作助手类
 */
public class ClassHelper {
    private static final Set<Class<?>> CLASS_SET ;
    static {
        String basePackage = ConfigHelper.getAppBasePackage();
        CLASS_SET = ClassUtil.getClassSet(basePackage);
    }

    /**
     * 获取所有的类
     * @return
     */
    public static Set<Class<?>> getClassSet(){
        return CLASS_SET;
    }

    /**
     * 获取应用包下所有的 Service 类
     * @return
     */
    public static Set<Class<?>> getServiceClassSet(){
        Set<Class<?>> classSet = CLASS_SET.stream().filter(cls-> cls.isAnnotationPresent(Service.class)).collect(Collectors.toSet());
        return classSet;
    }

    /**
     * 获取应用包下所有的 Controller 类
     * @return
     */
    public static Set<Class<?>> getControllerClassSet(){
        Set<Class<?>> classSet = CLASS_SET.stream().filter(cls-> cls.isAnnotationPresent(Controller.class)).collect(Collectors.toSet());
        return classSet;
    }

    public static Set<Class<?>> getBeanClassSet(){
        Set<Class<?>> classSet = new HashSet<>();
        classSet.addAll(getServiceClassSet());
        classSet.addAll(getControllerClassSet());
        return classSet;
    }

    /**
     * 获取应用包名下某父类（或接口）的所有子类（或实现类）
     * @param superClass
     * @return
     */
    public static Set<Class<?>> getClassSetBySuper(Class<?> superClass){
        Set<Class<?>> classSet =
                CLASS_SET.stream().filter(p->superClass.isAssignableFrom(p) && !superClass.equals(p)).collect(Collectors.toSet());
        return classSet;
    }

    /**
     * 获取应用包名下带有某注解的所有类
     * @param annotationClass
     * @return
     */
    public static Set<Class<?>> getClassSetByAnnotation(Class<? extends Annotation> annotationClass){
        Set<Class<?>> classSet =
                CLASS_SET.stream().filter(p->p.isAnnotationPresent(annotationClass)).collect(Collectors.toSet());
        return classSet;
    }
}
